package proxyskeleton;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.security.PrivilegedAction;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;

public class CreateGSSContextAction implements PrivilegedAction<GSSContext>{
	Socket socket;
	String servername;
	
	CreateGSSContextAction(Socket socket,String servername){
		this.socket=socket;
		this.servername=servername;
	}
	@Override
	public GSSContext run() {
		GSSContext context = null;
		try {
			//InputStream e OutputStream for context establishment
		    DataInputStream inStream = 
		  	  new DataInputStream(socket.getInputStream());
		  	DataOutputStream outStream = 
		  	  new DataOutputStream(socket.getOutputStream());
		    
		    Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
			GSSManager manager = GSSManager.getInstance();
			GSSName serverGSSName = manager.createName(servername, null);
			
			context = manager.createContext(serverGSSName,krb5Oid,null,GSSContext.DEFAULT_LIFETIME);
			
			context.requestMutualAuth(true);
			context.requestConf(true);
			context.requestInteg(true);
			
			byte[] token = new byte[0];
			while (!context.isEstablished()) {
				// token is ignored on the first call
				token = context.initSecContext(token, 0, token.length);
	
			    // Send a token to the server if one was generated by
			    // initSecContext
			    if (token != null) {
					outStream.writeInt(token.length);
					outStream.write(token);
					outStream.flush();
			    }
	
			    // If the client is done with context establishment
			    // then there will be no more tokens to read in this loop
			    if (!context.isEstablished()) {
					token = new byte[inStream.readInt()];
					inStream.readFully(token);
			    }
			}
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return context;
	}

}
